<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>
  </body>
  
  <script>
    /*面向对象类与构造函数*/
    class OOPClass {
      name = '';//创建name属性并初始化，若不初始化则可省略该行，但不建议省略
      
      constructor(name) {
        this.name = name;
      }
      
      classMethod() {
        console.log('classMethod：' + this.name)
      }
    }
    
    let oopClass = new OOPClass('OOPClass')
    oopClass.classMethod();//classMethod：OOPClass
    
    /*对象原型类与构造函数*/
    function PrototypeClass(name) {
      this.name = name
      
      this.classMethod = () => {
        console.log('classMethod：' + this.name)
      }
    }
    
    let prototypeClass = new PrototypeClass('PrototypeClass')
    prototypeClass.classMethod();//classMethod：PrototypeClass
    
    /*面向对象继承*/
    class OOPClassParent {
      constructor(name) {
        this.parentName = name;
      }
      
      classMethod() {
        console.log('classMethod：' + this.parentName)
      }
    }
    
    class OOPClassSon extends OOPClassParent {
      constructor(parentName, sonName) {
        super(parentName);//调用父类构造方法
        this.sonName = sonName;
      }
      
      classMethod() {//父类的classMethod方法被子类覆盖
        console.log('classMethod：' + this.sonName)
      }
    }
    
    let oopClassSon = new OOPClassSon("Parent", "Son");
    console.log(oopClassSon.parentName);//Parent
    console.log(oopClassSon.sonName);//Son
    oopClassSon.classMethod();//classMethod：Son
    
    /*封装*/
    class privateClass {
      #name;//声明私有属性
      
      constructor(name, age) {
        this.#name = name;
        //this.#age = age;//私有属性必须先声明，否则将报错
      }
      
      #privateMethod() {
        console.log(`privateMethod：${this.#name}`)
      }
      
      publicMethod() {
        this.#privateMethod();
      }
    }
    
    new privateClass('syx', 19).publicMethod();//privateMethod：syx
  </script>
</html>